home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_07_04 / v7n4041a.txt < prev    next >
Text File  |  1988-10-08  |  19KB  |  470 lines

  1. /*----------------------------------------------------------------*/
  2. /*    MODULE: AUDIR.C                                             */
  3. /*  CONTENTS: main()...                                           */
  4. /*    AUTHOR: John T. Bell                                        */
  5. /*   HISTORY: Last modified on 9/14/88                            */
  6. /*                                                                */
  7. /*  Copyright 1988, by John T. Bell, All Rights Reserved.         */
  8. /*----------------------------------------------------------------*/
  9. #include <stdio.h>
  10. #include <errno.h>
  11. #include "bios.h"
  12.  
  13. typedef unsigned char byte;
  14. typedef unsigned short word;
  15. /* turn off redefinitions in header files */
  16. #define BYTE_DEF
  17.  
  18. #include "prodir.h"
  19. #include "ados33.h"
  20. #include "cpmdir.h"
  21.  
  22. /*---------------------------------------------------*/
  23. /* Note: Slot 6, Drive 1, is the C: CP/M drive on my */
  24. /*       system. Drive C: is is referenced by the    */
  25. /*       Number 2 to the CP/M BIOS.                  */
  26. /*       A: == Drive 0                               */
  27. /*       B: == Drive 1                               */
  28. /*       C: == Drive 2                               */
  29. /*       Etc...                                      */
  30. /* Change as appropiate for your system.             */
  31. /*---------------------------------------------------*/
  32. #define DRIVE 2
  33.  
  34. /*----------------------------------------------------------*/
  35. /* This is a table of the first 4 bytes which should        */
  36. /* appear at track 0 sector 0 of each disk format           */
  37. /* expected. This is used to determine which                */
  38. /* operating system the disk was written with. The          */
  39. /* fifth byte in each row should identify the OS in         */
  40. /* the following manner;                                    */
  41. /*                                                          */
  42. /* CP/M  is 0x00                                            */
  43. /* AppleDOS is 0x01                                         */
  44. /* and ProDOS is 0x02                                       */
  45. /*                                                          */
  46. /* Note: The second CP/M entry is for a disk which has      */
  47. /* formatted but the CP/M boot tracks were not written.     */
  48. /*----------------------------------------------------------*/
  49. #define MAX_TYPE 4
  50. byte disk_id[ MAX_TYPE ][5] = {
  51.     { 0x01, 0xea, 0xa6, 0x2b, 0x00}, /* CP/M format */
  52.     { 0xe5, 0xe5, 0xe5, 0xe5, 0x00}, /* CP/M Disk w/o system */
  53.     { 0x01, 0xa5, 0x27, 0xc9, 0x01}, /* Apple Dos 3.3 Disk */
  54.     { 0x01, 0x38, 0xb0, 0x03, 0x02}  /* ProDOS 1.1.1 Disk  */
  55. };
  56.  
  57. /*---------------------------------------------------*/
  58. /* The following is the sector conversion table      */
  59. /* for converting DOS sectors to CP/M sectors.       */
  60. /*---------------------------------------------------*/
  61. int dos2cpm[] = {0,15,9,3, 13,7,1,11, 10,4,14,8, 2,12,6,5};
  62. int pro2cpm[] = {0,6,12,2, 8,14,4,10, 11,1,7,13, 3,9,15,5};
  63.  
  64. main()
  65. {
  66.     int type;
  67.     int err;
  68.  
  69.     type = disktype();
  70.     switch(type){
  71.     case 0: /* CP/M disk */
  72.         printf("*** CP/M Directory ***\n\n");
  73.         cpmdir();
  74.         break;
  75.  
  76.     case 1:
  77.         printf("*** Apple DOS 3.3 Directory ***\n\n");
  78.         dosdir();
  79.         break;
  80.  
  81.     case 2:
  82.         printf("*** ProDOS Directory ***\n\n");
  83.         prodir();
  84.         break;
  85.  
  86.     default:
  87.         printf("udir: Can't identify disk type\n");
  88.         break;
  89.     }
  90. /*--------------------------------------------------------*/
  91. /* The following, skips the Aztec CP/M exit code.         */
  92. /*--------------------------------------------------------*/
  93. #asm
  94.     .z80
  95.     jp 0
  96.     .8080
  97. #endasm
  98. }
  99.  
  100. /*--------------------------------------------------------------------------*/
  101. /*   Function: int disktype();                                              */
  102. /*    Purpose: Identify a diskette as being CP/M, AppleDOS, or ProDOS.      */
  103. /*    Returns: 0 for CP/M, 1 for AppleDOS, 2 for ProDOS,                    */
  104. /*             -1 for unidentified, and -2 for error.                       */
  105. /*    Globals: Uses the disk_id[][] table to compare the first four         */
  106. /*             bytes of the disk and make an identification.                */
  107. /*      Notes: Disk idents were determined by trial and error. There may    */
  108. /*             be others (ie; NON-Bootable AppleDOS) which have not been    */
  109. /*             included in the table.                                       */
  110. /*--------------------------------------------------------------------------*/
  111. int disktype()
  112. {
  113.     byte buff[128]; /* buffer for first track and sector */
  114.     byte *bptr;
  115.     int i,j;
  116.     int err;
  117.  
  118.     if((err = readsect(DRIVE,0,0,buff)) != 0){ /* disk error */
  119.         errno = err;
  120.         return(-2);
  121.     }
  122.  
  123.     for(i = 0; i < MAX_TYPE; i++){
  124.         bptr = buff;
  125.         for(j = 0; j < 4; j++){
  126.             if(disk_id[i][j] != *bptr++)
  127.                 break;
  128.         }
  129.         if(j >= 4)
  130.             return(disk_id[i][4] & 0x00ff);
  131.     }
  132.     return(-1);
  133. }
  134.  
  135. /*--------------------------------------------------------------------------*/
  136. /*   Function: cpmdir()                                                     */
  137. /*    Purpose: Do a low level (without CP/M BDOS assistance) read of the    */
  138. /*             CP/M directory. A low level directory read is needed here    */
  139. /*             to enable future porting to other Apple Operating Systems.   */
  140. /*    Returns: NONE                                                         */
  141. /*      Notes: Disk is currently hard coded and should be given as an arg   */
  142. /*             in the future.                                               */
  143. /*                                                                          */
  144. /*--------------------------------------------------------------------------*/
  145. cpmdir()
  146. {
  147.     char buff[128];  /* disk sector buffer */
  148.     int i,err;
  149.     int disk;
  150.     int track,sect;
  151.     struct cpm_entry *dir;
  152.     int user,j;
  153.  
  154.     track = 3; /* track for apple cp/m directory */
  155.  
  156.     for(sect = 0; sect < 12; sect++){
  157.         err = readsect(DRIVE,track,sect,buff);
  158.         if(!err){
  159.             dir = (struct cpm_entry *)buff;
  160.             for(j = 0; j < 4; j++){
  161.                 if((dir->user_no != 0xe5) /* skip erased file */
  162.                   &&(dir->extent == 0)){   /* and extra extents */
  163.                     user = dir->user_no & 0x1f;
  164.                     printf("C%d:%8.8s.%3.3s\n",user,dir->name,dir->ext);
  165.                 }
  166.                 dir++;
  167.             }
  168.         }
  169.     }
  170. }
  171.  
  172. /*--------------------------------------------------------------------------*/
  173. /*   Function: prodir()                                                     */
  174. /*    Purpose: This routine reads the Apple DOS directory from              */
  175. /*             a Pro Dos disk and prints it to the display.                 */
  176. /*    Returns: 0 if no error, -1 otherwise.                                 */
  177. /*      Notes: Requires PRODIR.H to define the structures.                  */
  178. /*                                                                          */
  179. /*--------------------------------------------------------------------------*/
  180. prodir()
  181. {
  182.     byte buff[513];  /* disk sector buffer */
  183.     byte fname[32];  /* space for filename */
  184.     int i,err;
  185.     int block;
  186.     struct pro_block *dir;
  187.     int entry_type;
  188.     int name_len;
  189.  
  190.     dir = (struct pro_block *)buff;
  191.     block = 2;
  192. /*---------------------------------------------------*/
  193. /* read sectors until no further catalog links       */
  194. /*---------------------------------------------------*/
  195.     do{
  196.         err = getproblock(block,buff); 
  197.         if(err){
  198.             fprintf(stderr,"error %d reading block %d\n",err,block);
  199.             return(-1);
  200.         }
  201.  
  202. /*---------------------------------------------------*/
  203. /* Print the directory entries                       */
  204. /*---------------------------------------------------*/
  205.         for(i = 0; i < 13; i++){
  206.             entry_type = (dir->dir[i].typ_len & 0x00f0) / 16;
  207.